package org.restoran.service.impl;

import com.google.common.base.Preconditions;
import org.restoran.model.Order;
import org.restoran.model.Table;
import org.restoran.model.TableStatus;
import org.restoran.repository.OrderRepository;
import org.restoran.repository.TableRepository;
import org.restoran.service.TableService;
import org.restoran.service.parser.Parser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Writer;
import java.util.Collection;


/**
 * @author Ievgen Pidvysotskyi
 */

@Service("tableService")
@Repository
@Transactional (propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class TableServiceImpl implements TableService {

    public static Logger logger = LoggerFactory.getLogger(TableServiceImpl.class);



	private final TableRepository tableRepository;
    private final OrderRepository orderRepository;
    private final Parser parser;

    @Autowired
    public TableServiceImpl(TableRepository tableRepository,
                            OrderRepository orderRepository,
                            Parser parser)
    {
        this.tableRepository = tableRepository;
        this.orderRepository = orderRepository;
        this.parser = parser;
    }

    @Override
    public Table findOne(Integer integer) {
        return tableRepository.findOne(integer);
    }

    @Override
    public Iterable<Table> findAll()
    {
        return tableRepository.findAll();
    }

    @Override
    public Table save(Table tab)
    {
        Preconditions.checkNotNull(tab, "Entity must not be null");
        Preconditions.checkArgument(tab.isNew(), "Save as new Table with id");

        return tableRepository.save(tab);
    }

    @Override
    public void delete(Table deleted)
    {
        tableRepository.delete(deleted);
    }

    @Override
    public void delete(Integer deletedId)
    {
        tableRepository.delete(deletedId);
    }

    @Override
    public String parseToJson(Table entity)
    {
        return parser.toJson(entity);
    }

    @Override
    public void parseToJson(Writer writer, Table entity) {
        parser.toJson(writer, entity);
    }

    @Override
    public String parseToJson(Collection<Table> objects) {
        return parser.toJson(objects);
    }

    @Override
    public void parseToJson(Writer writer, Collection<Table> args) {
        parser.toJson(writer, args);
    }

    @Override
    public Table parseFromJson(String json, Class<Table> type)
    {
        Table table = parser.fromJson(json, type);
        table.setOrder((table.getOrder() != null)
                ? orderRepository.findOne(table.getOrder().getId())
                : null);
        return table;
    }

    @Override
    public Order getOrderFromTableAsLazy(Table target) {
        return target.getOrder();
    }

    @Override
    public Table update(Table tab)
    {
        Preconditions.checkNotNull(tab);
        Preconditions.checkArgument(!tab.isNew(), "update not existed");

        return tableRepository.save(tab);
    }

}
